<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>apply</title>
</head>

<style>
  p {
    font-size: 12px;
  }
</style>
<body>
  <h4>理解了手写call之后，手写apply也自然触类旁通，只要注意两点即可。</h4>
  <p>myApply接受的第二个参数是数组形式。</p>
  <p>要考虑实际调用时不传第二个参数或者第二个参数不是数组的情况。</p>

</body>

<script>

  Function.prototype.myApply = function(thisArg, params) {
    // 严格模式 this 指向 undefined
    var isStrict = (function() {return this === undefined})
    
    if(!isStrict) {
      var thisArgType = typeof thisArg //指向的参数类型
      if(thisArgType === 'number'){
        thisArg = new Number(thisArg)
      } else if(thisArgType === 'string') {
        thisArg = new String(thisArg)
      } else if(thisArgType === 'boolean') {
        thisArg = new Boolean(thisArg)
      }
    }

    var invokeFunc = this;
    // 处理第二个参数
    var invokeParams = Array.isArray(params) ? params : [];
    // 1. 如果没有传指向对象， 那就直接将this 指向 全局 windows
    if(thisArg === null || thisArg === undefined) {
      return invokeFunc(...invokeParams)
    }

    // 2.
    var uniquePropName = Symbol(thisArg)
    thisArg[uniquePropName] = invokeFunc
    return thisArg[uniquePropName](...invokeParams)

  }

  // 调用
  let a = Math.max.myApply(null, [1, 2, 4, 8]);
  console.log(a) //8


</script>
</html>